package indi.zhifa.study2025.class004.imgserv.service.impl;

import cn.hutool.crypto.digest.DigestUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.support.config.FastJsonConfig;
import indi.zhifa.engine.core.common.crypto.MurmurHash3Util;
import indi.zhifa.engine.core.minio.util.IMinIoUtil;
import indi.zhifa.study2025.class004.imgserv.dao.gen.service.IGenPictureDbService;
import indi.zhifa.study2025.class004.imgserv.dao.mapper.PictureMapper;
import indi.zhifa.study2025.class004.imgserv.entity.dto.PictureRequest;
import indi.zhifa.study2025.class004.imgserv.entity.dto.PictureVecCalRequest;
import indi.zhifa.study2025.class004.imgserv.entity.po.GenPictureEntity;
import indi.zhifa.study2025.class004.imgserv.entity.vo.PictureVo;
import indi.zhifa.study2025.class004.imgserv.enums.ESourceType;
import indi.zhifa.study2025.class004.imgserv.service.IImageService;
import indi.zhifa.study2025.class004.imgserv.utils.ConstantUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.concurrent.Executor;

@RequiredArgsConstructor
@Component
public class ImageServiceImpl implements IImageService {

    final IGenPictureDbService mPictureDbService;
    final IMinIoUtil mMinIoUtil;
    final RestTemplate mRestTemplate;
    @Qualifier("backendExecutor")
    final Executor mExecutor;
    final RabbitTemplate mRabbitTemplate;
    @Qualifier("simple-fastJson-config")
    final FastJsonConfig mFastJsonConfig;

    protected GenPictureEntity upload(GenPictureEntity pPictureEntity, byte[] pData) {
        String fileFingerprint = MurmurHash3Util.getFileFingerprintBase64(pData);
        String md5 = DigestUtil.md5Hex(pData);
        GenPictureEntity stockPictureEntity = mPictureDbService.findByImgFingerprint(fileFingerprint,md5);
        if(null != stockPictureEntity){ // 说明该文件已经传过，只是源不同
            pPictureEntity.setUrl(stockPictureEntity.getUrl());
            pPictureEntity.setUrlFingerprint(stockPictureEntity.getUrlFingerprint());
            pPictureEntity.setImgMd5(stockPictureEntity.getImgMd5());
            pPictureEntity.setVecStatus(stockPictureEntity.getVecStatus());
            pPictureEntity.setCopyData(true);
        }else{
            String url = mMinIoUtil.putFile(Arrays.asList("class004"),pPictureEntity.getSuffix(),pData);
            int urlFingerPrint = MurmurHash3Util.getShortFingerprint(url);
            pPictureEntity.setUrl(url);
            pPictureEntity.setFileFingerprint(fileFingerprint);
            pPictureEntity.setUrlFingerprint(urlFingerPrint);
            pPictureEntity.setCopyData(false);
            pPictureEntity.setImgMd5(md5);
        }
        mPictureDbService.save(pPictureEntity);
        // 把计算任务推送到消息队列
        PictureVecCalRequest request = new PictureVecCalRequest();
        request.setId(pPictureEntity.getId());
        request.setUrl(pPictureEntity.getUrl());
        request.setCalTimes(0);
        byte[] jsonBytes = JSON.toJSONBytes(request,mFastJsonConfig.getWriterFeatures());
        mRabbitTemplate.send(ConstantUtil.PICTURE_VEC_CAL_KEY,new Message(jsonBytes));
        return pPictureEntity;
    }

    public PictureVo uploadFromUrl(PictureRequest pPictureRequest){
        pPictureRequest.determineSuffix();
        int urlFingerPrint = MurmurHash3Util.getShortFingerprint(pPictureRequest.getExtUrl());
        GenPictureEntity pictureEntity = mPictureDbService.findByUrl(pPictureRequest.getExtUrl(), urlFingerPrint);
        PictureVo rtn = new PictureVo();
        if(pictureEntity == null){
            pictureEntity = new GenPictureEntity();
            pictureEntity.createInit();
            pictureEntity.setUrl(pPictureRequest.getExtUrl());
            pictureEntity.setUrlFingerprint(urlFingerPrint);
            pictureEntity.setSuffix(pPictureRequest.getSuffix());
            pictureEntity.setSourceType(ESourceType.OUTER_URL);
            // 拉取图片数据
            byte[] data = mRestTemplate.getForObject(pPictureRequest.getExtUrl(),byte[].class);
            upload(pictureEntity,data);
        }
        rtn.setId(pictureEntity.getId());
        rtn.setUrl(pictureEntity.getUrl());
        return rtn;
    }

    public PictureVo uploadFromFile(MultipartFile pMultipartFile) throws IOException {
        InputStream fileInputStream = pMultipartFile.getInputStream();
        byte[] fileBytes = fileInputStream.readAllBytes();
        String fileFingerprint = MurmurHash3Util.getFileFingerprintBase64(fileBytes);
        String md5 = DigestUtil.md5Hex(fileBytes);

        GenPictureEntity stockPictureEntity = mPictureDbService.findByImgFingerprint(fileFingerprint,md5);
        if(null == stockPictureEntity){
            String orgFileName = pMultipartFile.getOriginalFilename();
            String suffix = StringUtils.getFilenameExtension(orgFileName);
            stockPictureEntity = new GenPictureEntity();
            stockPictureEntity.createInit();
            stockPictureEntity.setSourceType(ESourceType.BYTE);
            stockPictureEntity.setSuffix(suffix);
            upload(stockPictureEntity,fileBytes);
        }

        PictureVo rtn = new PictureVo();
        rtn.setUrl(stockPictureEntity.getUrl());
        rtn.setId(stockPictureEntity.getId());
        return rtn;
    }

}
